package com.security.door.utils.collectionUtil;




import com.google.common.collect.Lists;
import org.dozer.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.*;



public class CollectionUtil {

    public static Object[] createArray(Object... objects) {
        return objects.clone();
    }

    public static ArrayList<Long> toLongList(List<String> list) {
        if (list == null || list.isEmpty()) {
            return new ArrayList<Long>();
        }
        ArrayList<Long> result = new ArrayList<Long>();
        for (String str : list) {
            try {
                result.add(Long.parseLong(str));
            } catch (Exception ignore) {
            }
        }
        return result;
    }

    public static ArrayList<String> toStrList(List<?> list) {
        if (list == null || list.isEmpty()) {
            return new ArrayList<String>();
        }
        ArrayList<String> strList = new ArrayList<String>();
        for (Object id : list) {
            strList.add(String.valueOf(id));
        }
        return strList;
    }

    public static <T> List<T> getColumnValues(Collection<?> list, String columnName) {
        List<T> results = Lists.newArrayList();
        try {
            if (list == null || list.isEmpty()) {
                return results;
            }
            Field getField = null;
            for (Object one : list) {
                if (getField == null) {
                    getField = ReflectionUtils.getFieldFromBean(one.getClass(), columnName);
                    getField.setAccessible(true);
                }
                try {
                    Object o = getField.get(one);
                    if (o != null) {
                        results.add((T) o);
                    }
                } catch (Exception ignore) {
                }
            }
        } catch (Exception ignore) {
        }
        return results;
    }

    @Deprecated
    public static <K, S, G> void getAndSetValue(List<S> setBeanList, List<G> getBeanList, String keyName, String setColumnName) {
        getSetValue(getBeanList, setBeanList, keyName, keyName, createGetSetColumnNames(Arrays.asList(setColumnName, setColumnName)));
    }

    /**
     * 单个字段组装函数
     * 经测试，处理10W数据仅需50ms，比一般写法慢2倍
     *
     * @param getBeanList   拥有字段值的list
     * @param setBeanList   待填充字段值的list
     * @param beanKeyName   两个list“外键”的字段名
     * @param setColumnName 需要设置值的字段名
     */
    public static <K, S, G> void getSetValue(List<G> getBeanList, List<S> setBeanList, String beanKeyName, String setColumnName) {
        getSetValue(getBeanList, setBeanList, beanKeyName, beanKeyName, createGetSetColumnNames(Arrays.asList(setColumnName, setColumnName)));
    }

    /**
     * 多个字段组装函数，适用于“外键”名不一致的情况
     *
     * @param getBeanList    拥有字段值的list
     * @param setBeanList    待填充字段值的list
     * @param getBeanKeyName 两个list的“外键”之getBeanList的字段名
     * @param setBeanKeyName 两个list的“外键”之setBeanList的字段名
     * @param setColumnNames 需要设置值的字段名
     */
    public static <K, S, G> void getSetValue(List<G> getBeanList, List<S> setBeanList, String getBeanKeyName, String setBeanKeyName, String... setColumnNames) {
        List<String> columnNames = Lists.newArrayList();
        for (String setColumnName : setColumnNames) {
            columnNames.add(setColumnName);
            columnNames.add(setColumnName);
        }
        getSetValue(getBeanList, setBeanList, getBeanKeyName, setBeanKeyName, createGetSetColumnNames(columnNames));
    }

    /**
     * 多个字段组装函数，适用于待组装字段，名称不一致的情况
     *
     * @param getBeanList       待填充字段值的list
     * @param setBeanList       拥有字段值的list
     * @param beanKeyName       两个list“外键”的字段名
     * @param getSetColumnNames 需要设置值的字段名
     */
    public static <K, S, G> void getSetValue(List<G> getBeanList, List<S> setBeanList, String beanKeyName, List<GetSetColumnName> getSetColumnNames) {
        getSetValue(getBeanList, setBeanList, beanKeyName, beanKeyName, getSetColumnNames);
    }

    public static <K, S, G> void getSetValue(List<G> getBeanList, List<S> setBeanList, String getBeanKeyName,
                                             String setBeanKeyName, List<GetSetColumnName> getSetColumnNames) {
        Map<K, G> keyMap = MapUtil.toMap(getBeanList, getBeanKeyName);
        if (setBeanList == null || setBeanList.isEmpty() || getBeanList == null || getBeanList.isEmpty()) {
            return;
        }
        try {
            Field getField = ReflectionUtils.getFieldFromBean(setBeanList.get(0).getClass(), setBeanKeyName);
            getField.setAccessible(true);

            List<Field> getColumnNameFields = Lists.newArrayList();
            List<Field> setColumnNameFields = Lists.newArrayList();
            for (GetSetColumnName getSetColumnName : getSetColumnNames) {
                Field field1 = ReflectionUtils.getFieldFromBean(getBeanList.get(0).getClass(), getSetColumnName.getGetColumnName());
                field1.setAccessible(true);
                getColumnNameFields.add(field1);

                Field field = ReflectionUtils.getFieldFromBean(setBeanList.get(0).getClass(), getSetColumnName.getSetColumnName());
                field.setAccessible(true);
                setColumnNameFields.add(field);
            }
            for (S setObject : setBeanList) {
                try {
                    K key = (K) getField.get(setObject);
                    G getBean = keyMap.get(key);
                    if (getBean == null) {
                        continue;
                    }
                    for (int i = 0; i < getColumnNameFields.size(); i++) {
                        Object setColumnValue = getColumnNameFields.get(i).get(getBean);
                        setColumnNameFields.get(i).set(setObject, setColumnValue);
                    }
                } catch (Exception ignore) {
                }
            }
        } catch (Exception ignore) {
        }
    }

    public static List<GetSetColumnName> createGetSetColumnNames(List<String> columnNames) {
        List<GetSetColumnName> list = Lists.newArrayList();
        for (int i = 0; i < columnNames.size(); i++) {
            GetSetColumnName getSetColumnName = new GetSetColumnName();
            getSetColumnName.setGetColumnName(columnNames.get(i++));
            getSetColumnName.setSetColumnName(columnNames.get(i));
            list.add(getSetColumnName);
        }
        return list;
    }

    public static List<GetSetColumnName> createGetSetColumnNames(String... columnNames) {
        return createGetSetColumnNames(Arrays.asList(columnNames));
    }
}
